<?php
/**
 * 卡券管理
 *
 * @author Zeon <scplay@gmail.com>
 * @date 2019/5/7
 * @copyright PanxSoft Inc.
 */

namespace App\Http\Controllers\Wechat\V3_1;

use App\Http\Controllers\ApiController;
use App\Models\Coupon\CouponCard;
use App\Models\Coupon\CouponTicket;
use App\Models\Customer\Customer;
use App\Models\OpenWechat\WechatUser;
use App\Services\Utils\Random;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use function Sodium\crypto_box_publickey_from_secretkey;


class CouponTicketController extends ApiController
{
    const ROUTES = [
        'index'   => 'Wechat.v3_1.coupon-ticket.index',
        'lottery' => 'Wechat.v3_1.coupon-ticket.lottery',
    ];

    const HUNDRED_PERCENT = 1;


    public function index(Request $request)
    {
        /** @var Customer $customer */
        $customer = (new Customer)->find($request->get('customer_id'));
            $this->checkItemExist($customer, 'customer');

        $coupon_tickets = $customer
            ->couponTickets()
            ->where('is_available', CouponTicket::IS_AVAILABLE)
            ->latest()
            ->get();

        return $this->response(compact('coupon_tickets'));
    }

    /**
     * @param Request $request
     *
     * @return array|\Illuminate\Http\Response
     */
    public function lottery(Request $request)
    {
        /** @var Customer $customer */
        $customer = (new Customer)->find($request->get('customer_id'));
            $this->checkItemExist($customer, 'customer');

        $coupon_tickets = $customer
            ->couponTickets()
            ->where('is_available', CouponTicket::IS_AVAILABLE)
            ->get();
            $this->checkItemExist($coupon_tickets->count(), 'customer coupon tickets not find');

        $probabilities = $this->formatTicketIdProbabilities($coupon_tickets);

        $coupon_ticket = $coupon_tickets->find(Random::lottery($probabilities));

        return $this->response(compact('coupon_ticket'));
    }

    /**
     * @param Collection $coupon_tickets
     *
     * @return array
     */
    private function formatTicketIdProbabilities(Collection $coupon_tickets)
    {
        $probability_sum = $coupon_tickets->sum('probability');
        if ($probability_sum < self::HUNDRED_PERCENT) { // 如果概率合小于 1 补空值为重新抽奖或谢谢
            $null_probability = self::HUNDRED_PERCENT - $probability_sum;
            $coupon_tickets->push(new CouponTicket([
                'code'        => null,
                'probability' => $null_probability,
            ]));
        }

        $probability_accumulated = 0;
        $length_cnt = 1;
        $ticket_length = $coupon_tickets->count();
        $format_probabilities = [];

        /** @var CouponTicket $coupon_ticket */
        foreach ($coupon_tickets as $coupon_ticket) {
            $percent = number_format($coupon_ticket->probability / $probability_sum,
                2, '.', '');

            $probability_accumulated += $percent;
            if ($length_cnt === $ticket_length) { // last index must be "1"
                $probability_accumulated = self::HUNDRED_PERCENT;
            }

            // php 数组的 key 必须是 string 类型才会变成字典，否则 float 会默认转成 int 作数组的整数 index
            $format_probabilities[(string) $probability_accumulated] = $coupon_ticket->getKey();
            $length_cnt += 1;
        }

        uksort($format_probabilities, function (float $a, float $b) {
            return $b < $a;
        }); // sort key asc

        return $format_probabilities;
    }

}
